var validator = require('validator');
var urllib = require('urllib');
var querystring = require('querystring');


var WeiboApi = function () {
  this.api_hostname = 'api.weibo.com';
  // this.api_port = 433;
  this.api_root = 'https://' + this.api_hostname + '/2/';
  this.app_key = '';
  this.app_secret = '';
  this.redirect_uri = '';
  this.token = null;
  this.access_token = '';
};

module.exports = new WeiboApi();


var pt = WeiboApi.prototype;

pt.init = function (opt) {
  this.app_key = opt.app_key;
  this.app_secret = opt.app_secret;
  this.redirect_uri = opt.app_redirect_uri;
};


pt.apiRequest = function (apiName, options, callback) {
  var self = this;
  var url = self.api_root + apiName + '.json';
  options.data.access_token = self.access_token;
  console.log('apiRequest', apiName, url, options);
  urllib.request(url, options, function (err, data, res) {
    if (typeof callback == 'function') {
      if (err) {
        callback(err, null);
      } else {
        // console.log(res.statusCode);
        // console.log(res.headers);
        // data is Buffer instance
        // console.log(data.toString());
        callback(err, JSON.parse(data));
      }
    }
  });
};


pt._getOauthrizationURL = function () {
  var params = {
    client_id: this.app_key,
    redirect_uri: this.redirect_uri,
    response_type: 'code'
  };
  var query = querystring.stringify(params);
  return 'https://' + this.api_hostname + '/oauth2/authorize?' + query;
};


pt.authorize = function (res) {
  var url = this._getOauthrizationURL();
  // console.log('weibo.authorize', url);
  if (res.redirect) {
    res.redirect(url);
  } else {
    res.writeHead(302, {
      'Location': url
      //add other headers here...
    });
    res.end();
  }
};


pt.accessToken = function (code, callback) {
  var self = this;
  var url = 'https://' + self.api_hostname + '/oauth2/access_token';
  var params = {
    method: 'POST',
    data: {
      client_id: self.app_key,
      client_secret: self.app_secret,
      redirect_uri: self.redirect_uri,
      grant_type: 'authorization_code',
      code: code
    }
  };
  urllib.request(url, params, function (err, data, res) {
    // self.token = data;
    // self.access_token = data.access_token;
    // console.log(res.statusCode);
    // console.log(res.headers);
    // data is Buffer instance
    // console.log(data.toString());
    if (typeof callback == 'function') {
      if (err) {
        console.error(err);
      } else {
        callback(err, JSON.parse(data));
      }
    }
  });
};


// status  true  string  要发布的微博文本内容，必须做URLencode，内容不超过140个汉字。
// visible false int 微博的可见性，0：所有人能看，1：仅自己可见，2：密友可见，3：指定分组可见，默认为0。
// list_id false string  微博的保护投递指定分组ID，只有当visible参数为3时生效且必选。
// lat false float 纬度，有效范围：-90.0到+90.0，+表示北纬，默认为0.0。
// long  false float 经度，有效范围：-180.0到+180.0，+表示东经，默认为0.0。
// annotations false string  元数据，主要是为了方便第三方应用记录一些适合于自己使用的信息，每条微博可以包含一个或者多个元数据，必须以json字串的形式提交，字串长度不超过512个字符，具体内容可以自定。
// rip false string  开发者上报的操作用户真实IP，形如：211.156.0.1。
pt.statusesUpdate = function (params, callback) {
  var err = [];
  params.status = validator.trim(params.status);
  if (params.status.length === 0) {
    err.push('请输入内容');
  }
  if (params.status.length > 140) {
    err.push('内容不要超过140个字符');
  }
  if (err.length) {
    callback(err, null);
    return;
  }
  this.apiRequest('statuses/update', {
    method: 'POST',
    data: params
  }, callback);
};


// status  true  string  要发布的微博文本内容，必须做URLencode，内容不超过140个汉字。
// visible false int 微博的可见性，0：所有人能看，1：仅自己可见，2：密友可见，3：指定分组可见，默认为0。
// list_id false string  微博的保护投递指定分组ID，只有当visible参数为3时生效且必选。
// pic true  binary  要上传的图片，仅支持JPEG、GIF、PNG格式，图片大小小于5M。
// lat false float 纬度，有效范围：-90.0到+90.0，+表示北纬，默认为0.0。
// long  false float 经度，有效范围：-180.0到+180.0，+表示东经，默认为0.0。
// annotations false string  元数据，主要是为了方便第三方应用记录一些适合于自己使用的信息，每条微博可以包含一个或者多个元数据，必须以json字串的形式提交，字串长度不超过512个字符，具体内容可以自定。
// rip false string  开发者上报的操作用户真实IP，形如：211.156.0.1。
pt.statusesUpload = function (params, pic, callback) {
  var err = [];
  params.status = validator.trim(params.status);
  if (params.status.length === 0) {
    err.push('请输入内容');
  }
  if (params.status.length > 140) {
    err.push('内容不要超过140个字符');
  }
  if (err.length) {
    callback(err, null);
    return;
  }
  var self = this;
  var url = self.api_root + 'statuses/upload' + '.json';
  var boundary = 'boundary' + Date.now();
  var dash = '--';
  var crlf = '\r\n';

  params.access_token = self.access_token;
  /* RFC2388 */
  var builder = [];
  /* Generate headers. key */
  for (var key in params) {
    var item = dash + boundary + crlf;
    item += 'Content-Disposition: form-data; name="' + key + '"' + crlf + crlf;
    item += params[key];
    builder.push(item);
  }

  /* Generate headers. [PIC] */
  var item = dash + boundary + crlf;
  item += 'Content-Disposition: form-data; name="' + pic.field + '"; ';
  item += 'filename="' + pic.name + '"' + crlf;
  item += 'Content-Type: ' + pic.type + ';' + crlf + crlf;
  builder.push(item);
  builder = builder.join(crlf);

  /* Generate headers. end */
  var builderEnd = crlf + dash + boundary + dash +  crlf;
  // console.log('statusesUpload.builder');
  // console.log(Buffer.byteLength(builder), builder.length);
  // console.log(builder + builderEnd);

  var builderLength = Buffer.byteLength(builder);
  // var size = builderLength + pic.data.length + endstr.length;
  var size = builderLength + pic.data.length + builderEnd.length;
  var buffer = new Buffer(size);
  var offset = 0;
  buffer.write(builder);
  offset += builderLength;
  pic.data.copy(buffer, offset);
  offset += pic.data.length;
  buffer.write(builderEnd, offset);

  urllib.request(url, {
    headers: {
      'Content-type': 'multipart/form-data; boundary=' + boundary
    },
    method: 'POST',
    content: buffer
  }, function (err, data, res) {
    if (typeof callback == 'function') {
      if (err) {
        callback(err, null);
      } else {
        // console.log(res.statusCode);
        // console.log(res.headers);
        // data is Buffer instance
        // console.log(data.toString());
        callback(err, JSON.parse(data));
      }
    }
  });
};

// id  true  int64 要转发的微博ID。
// status  false string  添加的转发文本，必须做URLencode，内容不超过140个汉字，不填则默认为“转发微博”。
// is_comment  false int 是否在转发的同时发表评论，0：否、1：评论给当前微博、2：评论给原微博、3：都评论，默认为0 。
// rip false string  开发者上报的操作用户真实IP，形如：211.156.0.1。
pt.statusesRepost = function (params, callback) {
  var err = [];
  if (!validator.isInt(params.id)) {
    err.push('微博ID丢失');
  }
  params.status = validator.trim(params.status);
  if (params.status.length > 140) {
    err.push('内容不要超过140个字符');
  }
  if (err.length) {
    callback(err, null);
    return;
  }
  this.apiRequest('statuses/repost', {
    method: 'POST',
    data: params
  }, callback);
};

// id  true  int64 需要查询的微博ID。
// since_id  false int64 若指定此参数，则返回ID比since_id大的评论（即比since_id时间晚的评论），默认为0。
// max_id  false int64 若指定此参数，则返回ID小于或等于max_id的评论，默认为0。
// count false int 单页返回的记录条数，默认为50。
// page  false int 返回结果的页码，默认为1。
// filter_by_author  false int 作者筛选类型，0：全部、1：我关注的人、2：陌生人，默认为0。
pt.commentsShow = function (params, callback) {
  var err = [];
  if (!validator.isInt(params.id)) {
    err.push('微博ID丢失');
  }
  if (err.length) {
    callback(err, null);
    return;
  }
  this.apiRequest('comments/show', {
    method: 'GET',
    data: params
  }, callback);
};


pt.commentsCreate = function (params, callback) {
  var err = [];
  if (!validator.isInt(params.id)) {
    err.push('微博ID丢失');
  }
  params.comment = validator.trim(params.comment);
  if (params.comment.length === 0) {
    err.push('请输入内容');
  }
  if (params.comment.length > 140) {
    err.push('内容不要超过140个字符');
  }
  if (err.length) {
    callback(err, null);
    return;
  }
  this.apiRequest('comments/create', {
    method: 'POST',
    data: params
  }, callback);
};


pt.usersShow = function (params, callback) {
  if (params.uid) {
    delete params.screen_name;
  }
  this.apiRequest('users/show', {
    method: 'GET',
    data: params
  }, callback);
};


pt.friendshipsFollowers = function (params, callback) {
  if (params.uid) {
    delete params.screen_name;
  }
  this.apiRequest('friendships/followers', {
    method: 'GET',
    data: params
  }, callback);
};


pt.getWebImage = function (url, callback) {
  urllib.request(url, {
    method: 'GET'
  }, function (err, data, res) {
    // console.log(res.statusCode);
    // console.log(res.headers);
    // data is Buffer instance
    // console.log(data.toString());
    if (typeof callback == 'function') {
      if (err) {
        callback(err, null);
      } else {
        var pic = {
          length: res.headers['content-length'],
          type: res.headers['content-type'],
          data: data
        };
        callback(err, pic);
      }
    }
  });
};
